home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / gfx / 3d / irit50src.lha / irit5 / prsr_lib / iritprsb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-12  |  43.6 KB  |  1,146 lines

  1. /*****************************************************************************
  2. * Generic parser for the "Irit" solid modeller, in binary mode.             *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.1, Nov. 1993   *
  5. *****************************************************************************/
  6.  
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #include <math.h>
  10. #include <string.h>
  11. #include <setjmp.h>
  12. #include "irit_sm.h"
  13. #include "prsr_loc.h"
  14. #include "allocate.h"
  15. #include "attribut.h"
  16. #include "irit_soc.h"
  17.  
  18. #define BIN_FILE_SYNC_STAMP    0x30106000
  19.  
  20. typedef enum {
  21.     IP_OBJ_REG_TYPES = 199,     /* Seperator between regular and aux types. */
  22.     IP_OBJ_AUX_ATTR = 200,     /* These are the auxiliary objects/structs. */
  23.     IP_OBJ_AUX_VERTEX,
  24.     IP_OBJ_AUX_POLY,
  25.     IP_OBJ_AUX_CURVE,
  26.     IP_OBJ_AUX_SURFACE,
  27.     IP_OBJ_AUX_TRIMSRF,
  28.     IP_OBJ_AUX_TRIMCRV,
  29.     IP_OBJ_AUX_TRIMCRVSEG,
  30.     IP_OBJ_AUX_TRIVAR,
  31.     IP_OBJ_AUX_MATRIX,
  32.     IP_OBJ_AUX_STRING,
  33.     IP_OBJ_AUX_OLST,
  34.     IP_OBJ_AUX_END
  35. } IPObjAuxStructType;
  36.  
  37. static int
  38.     GlblLastSync = -1;
  39.  
  40. static void InputUnGetBinSync(int Sync);
  41. static int InputGetBinSync(int Handler, int Abort);
  42. static VoidPtr InputGetBinBlock(int Handler, VoidPtr Block, int Size);
  43. static void OutputPutBinSync(int Handler, int Type);
  44. static void OutputPutBinBlock(int Handler, VoidPtr Block, int Size);
  45. static void IritPrsrGetBinObjectAux(int Handler,
  46.                     IPObjectStruct *PObjParent,
  47.                     int Sync);
  48. static IPPolygonStruct *InputGetBinPolys(int Handler, int IsPolygon);
  49. static CagdCrvStruct *InputGetBinCurves(int Handler);
  50. static CagdSrfStruct *InputGetBinSurfaces(int Handler);
  51. static TrimSrfStruct *InputGetBinTrimSrfs(int Handler);
  52. static TrivTVStruct *InputGetBinTrivars(int Handler);
  53. static MatrixType *InputGetBinMatrix(int Handler);
  54. static char *InputGetBinString(int Handler);
  55. static IPObjectStruct **InputGetBinOList(int Handler, int Len);
  56. static IPAttributeStruct *InputGetBinAttributes(int Handler);
  57. static void OutputPutBinPolys(int Handler, IPPolygonStruct *Pl);
  58. static void OutputPutBinCurves(int Handler, CagdCrvStruct *Crv);
  59. static void OutputPutBinSurfaces(int Handler, CagdSrfStruct *Srf);
  60. static void OutputPutBinTrimSrfs(int Handler, TrimSrfStruct *TrimSrf);
  61. static void OutputPutBinTrivars(int Handler, TrivTVStruct *Trivar);
  62. static void OutputPutBinAttributes(int Handler, IPAttributeStruct *Attrs);
  63.  
  64. /*****************************************************************************
  65. * DESCRIPTION:                                                               *
  66. * Routine to unget a sync stamp from input stream.                 *
  67. *                                                                            *
  68. * PARAMETERS:                                                                *
  69. *   Sync:     To unget.                                                      *
  70. *                                                                            *
  71. * RETURN VALUE:                                                              *
  72. *   None                                     *
  73. *****************************************************************************/
  74. static void InputUnGetBinSync(int Sync)
  75. {
  76.     GlblLastSync = Sync;
  77. }
  78.  
  79. /*****************************************************************************
  80. * DESCRIPTION:                                                               *
  81. * Routine to get a sync stamp from input stream.                 *
  82. *   Returns zero if no input is available.                     *
  83. *                                                                            *
  84. * PARAMETERS:                                                                *
  85. *   Handler:   A handler to the open stream.                     *
  86. *   Abort:    Should we abort with fatal error if no sync!?             *
  87. *                                                                            *
  88. * RETURN VALUE:                                                              *
  89. *   int:      Type of object stamp or 0 of no sync.                          *
  90. *****************************************************************************/
  91. static int InputGetBinSync(int Handler, int Abort)
  92. {
  93.     unsigned long l;
  94.  
  95.     if (GlblLastSync >= 0) {
  96.     l = GlblLastSync;
  97.     GlblLastSync = -1;
  98.     return l;
  99.     }
  100.  
  101.     InputGetBinBlock(Handler, (VoidPtr) &l, sizeof(long));
  102.  
  103.     if ((l & 0xffffff00) == BIN_FILE_SYNC_STAMP) {
  104.     return l & 0xff;
  105.     }
  106.     else {
  107.     if (Abort)
  108.         _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ,
  109.                "Fail to sync on binary stream.");
  110.  
  111.     return -1;
  112.     }
  113. }
  114.  
  115. /*****************************************************************************
  116. * DESCRIPTION:                                                               *
  117. * Routine to get a block of character from input stream.             *
  118. *    If input returns EOF blocks until new inputs arrive (can happen if      *
  119. * reading from a non io blocked socket).                     *
  120. *    If Block is NULL a new block with the right Size is allocated.         *
  121. *                                                                            *
  122. * PARAMETERS:                                                                *
  123. *   Handler:   A handler to the open stream.                     *
  124. *   Block:     Where read block should go to.                                *
  125. *   Size:      Size of block to read.                                        *
  126. *                                                                            *
  127. * RETURN VALUE:                                                              *
  128. *   VoidPtr    Read data. Same as Block if given Block was not NULL.         *
  129. *****************************************************************************/
  130. static VoidPtr InputGetBinBlock(int Handler, VoidPtr Block, int Size)
  131. {
  132.     int c;
  133.     char
  134.     *p = (char *) Block;
  135.  
  136.     if (Block == NULL)
  137.         Block = IritMalloc(Size);
  138.  
  139.     while (Size-- > 0) {
  140.     if (_IPStream[Handler].f == NULL) {
  141.         while ((c = SocReadCharNonBlock(Handler)) == EOF) {
  142.         IritSleep(10);
  143.         }
  144.     }
  145.     else
  146.         c = getc(_IPStream[Handler].f);
  147.  
  148.     *p++ = c;
  149.     }
  150.  
  151.     return Block;
  152. }
  153.  
  154. /*****************************************************************************
  155. * DESCRIPTION:                                                               *
  156. * Routine to put a sync stamp to output stream.                     *
  157. *                                                                            *
  158. * PARAMETERS:                                                                *
  159. *   Handler:   A handler to the open stream.                     *
  160. *   Type:      Type of stamp.                                                *
  161. *                                                                            *
  162. * RETURN VALUE:                                                              *
  163. *   void                                                                     *
  164. *****************************************************************************/
  165. static void OutputPutBinSync(int Handler, int Type)
  166. {
  167.     unsigned long l = (Type | BIN_FILE_SYNC_STAMP);
  168.  
  169.     OutputPutBinBlock(Handler, (VoidPtr) &l, sizeof(long));
  170. }
  171.  
  172. /*****************************************************************************
  173. * DESCRIPTION:                                                               *
  174. * Routine to put a block of character to output stream.                 *
  175. *                                                                            *
  176. * PARAMETERS:                                                                *
  177. *   Handler:  A handler to the open stream.                     *
  178. *   Block:    Block to write.                                                *
  179. *   Size:     Size of Block.                                                 *
  180. *                                                                            *
  181. * RETURN VALUE:                                                              *
  182. *   void                                                                     *
  183. *****************************************************************************/
  184. static void OutputPutBinBlock(int Handler, VoidPtr Block, int Size)
  185. {
  186.     if (_IPStream[Handler].f == NULL) {
  187.     SocWriteLine(Handler, Block, Size);
  188.     }
  189.     else
  190.         fwrite(Block, Size, 1, _IPStream[Handler].f);
  191. }
  192.  
  193. /*****************************************************************************
  194. * DESCRIPTION:                                                               M
  195. * Routine to read one object from a given binary file, directly.         M
  196. *   Objects may be recursively defined (as lists), in which case all are     M
  197. * read in this single call.                             M
  198. *                                                                            *
  199. * PARAMETERS:                                                                M
  200. *   Handler:  A handler to the open stream.                     M
  201. *                                                                            *
  202. * RETURN VALUE:                                                              M
  203. *   IPObjectStruct *:    Read object.                                        M
  204. *                                                                            *
  205. * KEYWORDS:                                                                  M
  206. *   IritPrsrGetBinObject, files, parser                                      M
  207. *****************************************************************************/
  208. IPObjectStruct *IritPrsrGetBinObject(int Handler)
  209. {
  210.     IPObjectStruct
  211.     *PObjList = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  212.     int Sync,
  213.     Flatten = IritPrsrSetFlattenObjects(FALSE),
  214.     ObjCount = 0;
  215.  
  216.     /* If the following gain control and is non zero - its from error! */
  217.     if (setjmp(_IritPrsrLongJumpBuffer) != 0) {
  218.     /* Error had occured (and will be reported). Return something... */
  219.     PObjList -> ObjType = IP_OBJ_NUMERIC;
  220.     PObjList -> U.R = 0.0;
  221.     return PObjList;
  222.     }
  223.  
  224.     do {
  225.     /* If Sync is for a new object - get the object: */
  226.     if ((Sync = InputGetBinSync(Handler, FALSE)) < IP_OBJ_REG_TYPES &&
  227.         Sync >= 0) {
  228.         IPObjectStruct
  229.         *PObjParent = IPAllocObject("", IP_OBJ_UNDEF, NULL);
  230.  
  231.         IritPrsrGetBinObjectAux(Handler, PObjParent, Sync);
  232.         ListObjectInsert(PObjList, ObjCount++, PObjParent);
  233.     }
  234.     }
  235.     while (!_IritPrsrReadOneObject && Sync < IP_OBJ_REG_TYPES && Sync > -1);
  236.  
  237.     ListObjectInsert(PObjList, ObjCount++, NULL);
  238.  
  239.     /* If it is not a sync for an object structure, unget it. */
  240.     if (Sync >= IP_OBJ_REG_TYPES)
  241.     InputUnGetBinSync(Sync);
  242.  
  243.     PObjList = IritPrsrProcessReadObject(PObjList);
  244.  
  245.     IritPrsrSetFlattenObjects(Flatten);
  246.  
  247.     return(PObjList);
  248. }
  249.  
  250. /*****************************************************************************
  251. * DESCRIPTION:                                                               *
  252. * Routine to read one object from a given binary file, directly.         *
  253. *   Objects may be recursively defined (as lists), in which case all are     *
  254. * read in this single call.                             *
  255. *                                                                            *
  256. * PARAMETERS:                                                                *
  257. *   Handler:   A handler to the open stream.                     *
  258. *   PObjParent:  One list object, this read object should be hooked as an    *
  259. *                element.                             *
  260. *   Sync:     Binary stream sync value.                     *
  261. *                                                                            *
  262. * RETURN VALUE:                                                              *
  263. *   void                                                                     *
  264. *****************************************************************************/
  265. static void IritPrsrGetBinObjectAux(int Handler,
  266.                     IPObjectStruct *PObjParent,
  267.                     int Sync)
  268. {
  269.     InputGetBinBlock(Handler, (VoidPtr) PObjParent, sizeof(IPObjectStruct));
  270.     PObjParent -> Pnext = NULL;
  271.     PObjParent -> Count = 1;
  272.  
  273.     if (PObjParent -> Attrs)
  274.     PObjParent -> Attrs = InputGetBinAttributes(Handler);
  275.  
  276.     switch (Sync) {
  277.     case IP_OBJ_POLY:
  278.         PObjParent -> U.Pl =
  279.         InputGetBinPolys(Handler, IP_IS_POLYGON_OBJ(PObjParent));
  280.         break;
  281.     case IP_OBJ_NUMERIC:
  282.         break;
  283.     case IP_OBJ_POINT:
  284.         break;
  285.     case IP_OBJ_VECTOR:
  286.         break;
  287.     case IP_OBJ_PLANE:
  288.         break;
  289.     case IP_OBJ_MATRIX:
  290.         PObjParent -> U.Mat = InputGetBinMatrix(Handler);
  291.  
  292.         if (stricmp(PObjParent -> Name, "VIEW_MAT") == 0) {
  293.         IritPrsrWasViewMat = TRUE;
  294.         MAT_COPY(IritPrsrViewMat, PObjParent -> U.Mat);
  295.         }
  296.         else if (stricmp(PObjParent -> Name, "PRSP_MAT") == 0) {
  297.         IritPrsrWasPrspMat = TRUE;
  298.         MAT_COPY(IritPrsrPrspMat, PObjParent -> U.Mat);
  299.         }
  300.         break;
  301.     case IP_OBJ_CURVE:
  302.         PObjParent -> U.Crvs = InputGetBinCurves(Handler);
  303.         break;
  304.     case IP_OBJ_SURFACE:
  305.         PObjParent -> U.Srfs = InputGetBinSurfaces(Handler);
  306.         break;
  307.     case IP_OBJ_TRIMSRF:
  308.         PObjParent -> U.TrimSrfs = InputGetBinTrimSrfs(Handler);
  309.         break;
  310.     case IP_OBJ_TRIVAR:
  311.         PObjParent -> U.Trivars = InputGetBinTrivars(Handler);
  312.         break;
  313.     case IP_OBJ_STRING:
  314.         PObjParent -> U.Str = InputGetBinString(Handler);
  315.         break;
  316.     case IP_OBJ_LIST_OBJ:
  317.         PObjParent -> U.Lst.PObjList =
  318.         InputGetBinOList(Handler, PObjParent -> U.Lst.ListMaxLen);
  319.         break;
  320.     case IP_OBJ_CTLPT:
  321.         break;
  322.     default:
  323.         _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  324.     }
  325.  
  326.     if (Sync != IP_OBJ_LIST_OBJ &&
  327.     AttrGetObjectColor(PObjParent) == IP_ATTR_NO_COLOR)
  328.         AttrSetObjectColor(PObjParent, IP_LOAD_COLOR);
  329. }
  330.  
  331. /*****************************************************************************
  332. * DESCRIPTION:                                                               *
  333. * Routine to get a list of polys from bin input stream.                 *
  334. *                                                                            *
  335. * PARAMETERS:                                                                *
  336. *   Handler:   A handler to the open stream.                     *
  337. *   IsPolygon: Should we treat them as polygons?                             *
  338. *                                                                            *
  339. * RETURN VALUE:                                                              *
  340. *   IPPolygonStruct *:  Read list of polygons.                               *
  341. *****************************************************************************/
  342. static IPPolygonStruct *InputGetBinPolys(int Handler, int IsPolygon)
  343. {
  344.     int PSync;
  345.     IPPolygonStruct
  346.     *PHead = NULL,
  347.     *PTail = NULL;
  348.  
  349.     while ((PSync = InputGetBinSync(Handler, TRUE)) == IP_OBJ_AUX_POLY) {
  350.     int VSync;
  351.     IPPolygonStruct
  352.         *Poly = IPAllocPolygon(0, 0, NULL, NULL);
  353.     IPVertexStruct *Vrtx,
  354.         *VTail = NULL;
  355.  
  356.     InputGetBinBlock(Handler, (VoidPtr) Poly, sizeof(IPPolygonStruct));
  357.     if (Poly -> Attrs)
  358.         Poly -> Attrs = InputGetBinAttributes(Handler);
  359.  
  360.     Poly -> PVertex = NULL;
  361.     while ((VSync = InputGetBinSync(Handler, TRUE)) == IP_OBJ_AUX_VERTEX) {
  362.         Vrtx = IPAllocVertex(0, 0, NULL, NULL);
  363.         InputGetBinBlock(Handler, (VoidPtr) Vrtx, sizeof(IPVertexStruct));
  364.         if (Vrtx -> Attrs)
  365.         Vrtx -> Attrs = InputGetBinAttributes(Handler);
  366.  
  367.         if (Poly -> PVertex) {
  368.             VTail -> Pnext = Vrtx;
  369.         VTail = Vrtx;
  370.         }
  371.         else {
  372.         VTail = Poly -> PVertex = Vrtx;
  373.         }
  374.     }
  375.     if (_IritPrsrPolyListCirc)
  376.         VTail -> Pnext = Poly -> PVertex;
  377.     else
  378.         VTail -> Pnext = NULL;
  379.     if (VSync != IP_OBJ_AUX_END)
  380.         _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  381.  
  382.     if (IsPolygon) {
  383.         if (!IP_HAS_PLANE_POLY(Poly))
  384.         IritPrsrUpdatePolyPlane(Poly);
  385.  
  386.         IritPrsrUpdateVrtxNrml(Poly, Poly -> Plane);
  387.     }
  388.  
  389.     if (PHead) {
  390.         PTail -> Pnext = Poly;
  391.         PTail = Poly;
  392.     }
  393.     else {
  394.         PHead = PTail = Poly;
  395.     }
  396.     }
  397.     if (PSync != IP_OBJ_AUX_END)
  398.     _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  399.  
  400.     if (PTail)
  401.     PTail -> Pnext = NULL;
  402.  
  403.     if (PHead == NULL)
  404.     _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  405.  
  406.     return PHead;
  407. }
  408.  
  409. /*****************************************************************************
  410. * DESCRIPTION:                                                               *
  411. * Routine to get a list of curves from bin input stream.             *
  412. *                                                                            *
  413. * PARAMETERS:                                                                *
  414. *   Handler:   A handler to the open stream.                     *
  415. *                                                                            *
  416. * RETURN VALUE:                                                              *
  417. *   CagdCrvStruct *:   Read list of curves.                                  *
  418. *****************************************************************************/
  419. static CagdCrvStruct *InputGetBinCurves(int Handler)
  420. {
  421.     int i, Sync, Size;
  422.     CagdCrvStruct *Crv,
  423.     *CHead = NULL,
  424.     *CTail = NULL;
  425.  
  426.     while ((Sync = InputGetBinSync(Handler, TRUE)) == IP_OBJ_AUX_CURVE) {
  427.     Crv = (CagdCrvStruct *) IritMalloc(sizeof(CagdCrvStruct));
  428.     InputGetBinBlock(Handler, (VoidPtr) Crv, sizeof(CagdCrvStruct));
  429.     Crv -> Attr = NULL;
  430.     Crv -> Pnext = NULL;
  431.     Size = sizeof(CagdRType) * Crv -> Length;
  432.  
  433.     for (i = !CAGD_IS_RATIONAL_PT(Crv -> PType);
  434.          i <= CAGD_NUM_OF_PT_COORD(Crv -> PType);
  435.          i++) {
  436.         Crv -> Points[i] = (CagdRType *) IritMalloc(Size);
  437.         InputGetBinBlock(Handler, (VoidPtr) (Crv -> Points[i]), Size);
  438.     }
  439.  
  440.     for (i = CAGD_NUM_OF_PT_COORD(Crv -> PType) + 1;
  441.          i <= CAGD_MAX_PT_COORD;
  442.          i++)
  443.         Crv -> Points[i] = NULL;
  444.  
  445.     if (Crv -> GType == CAGD_CBSPLINE_TYPE) {
  446.         Size = sizeof(CagdRType) *
  447.                   (Crv -> Length + Crv -> Order +
  448.                    (Crv -> Periodic ? Crv -> Order - 1 : 0));
  449.         Crv -> KnotVector = (CagdRType *) IritMalloc(Size);
  450.         InputGetBinBlock(Handler, (VoidPtr) (Crv -> KnotVector), Size);
  451.     }
  452.  
  453.     if (CHead == NULL) {
  454.         CHead = CTail = Crv;
  455.     }
  456.     else {
  457.         CTail -> Pnext = Crv;
  458.         CTail = Crv;
  459.     }
  460.     }
  461.     if (Sync != IP_OBJ_AUX_END)
  462.     _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  463.  
  464.     if (CHead == NULL)
  465.     _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  466.  
  467.     return CHead;
  468. }
  469.  
  470. /*****************************************************************************
  471. * DESCRIPTION:                                                               *
  472. * Routine to get a list of surfaces from bin input stream.             *
  473. *                                                                            *
  474. * PARAMETERS:                                                                *
  475. *   Handler:   A handler to the open stream.                     *
  476. *                                                                            *
  477. * RETURN VALUE:                                                              *
  478. *   CagdSrfStruct *:    Read list of surfaces.                               *
  479. *****************************************************************************/
  480. static CagdSrfStruct *InputGetBinSurfaces(int Handler)
  481. {
  482.     int i, Sync, Size;
  483.     CagdSrfStruct *Srf,
  484.     *SHead = NULL,
  485.     *STail = NULL;
  486.  
  487.     while ((Sync = InputGetBinSync(Handler, TRUE)) == IP_OBJ_AUX_SURFACE) {
  488.     Srf = (CagdSrfStruct *) IritMalloc(sizeof(CagdSrfStruct));
  489.     InputGetBinBlock(Handler, (VoidPtr) Srf, sizeof(CagdSrfStruct));
  490.     Srf -> Attr = NULL;
  491.     Srf -> Pnext = NULL;
  492.     Size = sizeof(CagdRType) * Srf -> ULength * Srf -> VLength;
  493.  
  494.     for (i = !CAGD_IS_RATIONAL_PT(Srf -> PType);
  495.          i <= CAGD_NUM_OF_PT_COORD(Srf -> PType);
  496.          i++) {
  497.         Srf -> Points[i] = (CagdRType *) IritMalloc(Size);
  498.         InputGetBinBlock(Handler, (VoidPtr) (Srf -> Points[i]), Size);
  499.     }
  500.  
  501.     for (i = CAGD_NUM_OF_PT_COORD(Srf -> PType) + 1;
  502.          i <= CAGD_MAX_PT_COORD;
  503.          i++)
  504.         Srf -> Points[i] = NULL;
  505.  
  506.     if (Srf -> GType == CAGD_SBSPLINE_TYPE) {
  507.         Size = sizeof(CagdRType) *
  508.             (Srf -> ULength + Srf -> UOrder +
  509.              (Srf -> UPeriodic ? Srf -> UOrder - 1 : 0));
  510.         Srf -> UKnotVector = (CagdRType *) IritMalloc(Size);
  511.         InputGetBinBlock(Handler, (VoidPtr) (Srf -> UKnotVector), Size);
  512.         Size = sizeof(CagdRType) *
  513.             (Srf -> VLength + Srf -> VOrder +
  514.              (Srf -> VPeriodic ? Srf -> VOrder - 1 : 0));
  515.         Srf -> VKnotVector = (CagdRType *) IritMalloc(Size);
  516.         InputGetBinBlock(Handler, (VoidPtr) (Srf -> VKnotVector), Size);
  517.     }
  518.  
  519.     if (SHead == NULL) {
  520.         SHead = STail = Srf;
  521.     }
  522.     else {
  523.         STail -> Pnext = Srf;
  524.         STail = Srf;
  525.     }
  526.     }
  527.     if (Sync != IP_OBJ_AUX_END || SHead == NULL)
  528.     _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  529.  
  530.     return SHead;
  531. }
  532.  
  533. /*****************************************************************************
  534. * DESCRIPTION:                                                               *
  535. * Routine to get a list of trimmed surfaces from bin input stream.         *
  536. *                                                                            *
  537. * PARAMETERS:                                                                *
  538. *   Handler:   A handler to the open stream.                     *
  539. *                                                                            *
  540. * RETURN VALUE:                                                              *
  541. *   TrimSrfStruct *:    Read list of trimm surfaces.                         *
  542. *****************************************************************************/
  543. static TrimSrfStruct *InputGetBinTrimSrfs(int Handler)
  544. {
  545.     int Sync;
  546.     TrimSrfStruct *TrimSrf,
  547.     *SHead = NULL,
  548.     *STail = NULL;
  549.  
  550.     while ((Sync = InputGetBinSync(Handler, TRUE)) == IP_OBJ_AUX_TRIMSRF) {
  551.     TrimCrvStruct *TrimCrv,
  552.         *CHead = NULL,
  553.         *CTail = NULL;
  554.  
  555.     TrimSrf = (TrimSrfStruct *) IritMalloc(sizeof(TrimSrfStruct));
  556.     InputGetBinBlock(Handler, (VoidPtr) TrimSrf, sizeof(TrimSrfStruct));
  557.     TrimSrf -> Attr = NULL;
  558.     TrimSrf -> Pnext = NULL;
  559.     TrimSrf -> Srf = InputGetBinSurfaces(Handler);
  560.  
  561.     while ((Sync = InputGetBinSync(Handler, TRUE)) == IP_OBJ_AUX_TRIMCRV) {
  562.         TrimCrvSegStruct *TrimCrvSeg,
  563.             *CSHead = NULL,
  564.         *CSTail = NULL;
  565.  
  566.         TrimCrv = (TrimCrvStruct *) IritMalloc(sizeof(TrimCrvStruct));
  567.         InputGetBinBlock(Handler, (VoidPtr) TrimCrv, sizeof(TrimCrvStruct));
  568.         TrimCrv -> Attr = NULL;
  569.         TrimCrv -> Pnext = NULL;
  570.  
  571.         while ((Sync = InputGetBinSync(Handler, TRUE)) == IP_OBJ_AUX_TRIMCRVSEG) {
  572.         TrimCrvSeg = (TrimCrvSegStruct *)
  573.                     IritMalloc(sizeof(TrimCrvSegStruct));
  574.         InputGetBinBlock(Handler, (VoidPtr) TrimCrvSeg,
  575.                             sizeof(TrimCrvSegStruct));
  576.         TrimCrvSeg -> Attr = NULL;
  577.         TrimCrvSeg -> Pnext = NULL;
  578.         TrimCrvSeg -> EucCrv = NULL;
  579.         TrimCrvSeg -> UVCrv = InputGetBinCurves(Handler);
  580.  
  581.         if (CSHead == NULL) {
  582.             CSHead = CSTail = TrimCrvSeg;
  583.         }
  584.         else {
  585.             CSTail -> Pnext = TrimCrvSeg;
  586.             CSTail = TrimCrvSeg;
  587.         }
  588.          }
  589.         if (Sync != IP_OBJ_AUX_END || CSHead == NULL)
  590.         _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  591.  
  592.         TrimCrv -> TrimCrvSegList = CSHead;
  593.  
  594.         if (CHead == NULL) {
  595.         CHead = CTail = TrimCrv;
  596.         }
  597.         else {
  598.         CTail -> Pnext = TrimCrv;
  599.         CTail = TrimCrv;
  600.         }
  601.     }
  602.     if (Sync != IP_OBJ_AUX_END || CHead == NULL)
  603.         _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  604.  
  605.     TrimSrf -> TrimCrvList = CHead;
  606.  
  607.     if (SHead == NULL) {
  608.         SHead = STail = TrimSrf;
  609.     }
  610.     else {
  611.         STail -> Pnext = TrimSrf;
  612.         STail = TrimSrf;
  613.     }
  614.     }
  615.     if (Sync != IP_OBJ_AUX_END || SHead == NULL)
  616.     _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  617.  
  618.     return SHead;
  619. }
  620.  
  621. /*****************************************************************************
  622. * DESCRIPTION:                                                               *
  623. * Routine to get a list of surfaces from bin input stream.             *
  624. *                                                                            *
  625. * PARAMETERS:                                                                *
  626. *   Handler:   A handler to the open stream.                     *
  627. *                                                                            *
  628. * RETURN VALUE:                                                              *
  629. *   CagdSrfStruct *:    Read list of surfcaes.                               *
  630. *****************************************************************************/
  631. static TrivTVStruct *InputGetBinTrivars(int Handler)
  632. {
  633.     int i, Sync, Size;
  634.     TrivTVStruct *TV,
  635.     *SHead = NULL,
  636.     *STail = NULL;
  637.  
  638.     while ((Sync = InputGetBinSync(Handler, TRUE)) == IP_OBJ_AUX_TRIVAR) {
  639.     TV = (TrivTVStruct *) IritMalloc(sizeof(TrivTVStruct));
  640.     InputGetBinBlock(Handler, (VoidPtr) TV, sizeof(TrivTVStruct));
  641.     TV -> Attr = NULL;
  642.     TV -> Pnext = NULL;
  643.     Size = sizeof(CagdRType) *
  644.                 TV -> ULength * TV -> VLength * TV -> WLength;
  645.  
  646.     for (i = !CAGD_IS_RATIONAL_PT(TV -> PType);
  647.          i <= CAGD_NUM_OF_PT_COORD(TV -> PType);
  648.          i++) {
  649.         TV -> Points[i] = (CagdRType *) IritMalloc(Size);
  650.         InputGetBinBlock(Handler, (VoidPtr) (TV -> Points[i]), Size);
  651.     }
  652.  
  653.     for (i = CAGD_NUM_OF_PT_COORD(TV -> PType) + 1;
  654.          i <= CAGD_MAX_PT_COORD;
  655.          i++)
  656.         TV -> Points[i] = NULL;
  657.  
  658.     if (TV -> GType == TRIV_TVBSPLINE_TYPE) {
  659.         Size = sizeof(CagdRType) *
  660.             (TV -> ULength + TV -> UOrder +
  661.              (TV -> UPeriodic ? TV -> UOrder - 1 : 0));
  662.         TV -> UKnotVector = (CagdRType *) IritMalloc(Size);
  663.         InputGetBinBlock(Handler, (VoidPtr) (TV -> UKnotVector), Size);
  664.         Size = sizeof(CagdRType) *
  665.             (TV -> VLength + TV -> VOrder +
  666.              (TV -> VPeriodic ? TV -> VOrder - 1 : 0));
  667.         TV -> VKnotVector = (CagdRType *) IritMalloc(Size);
  668.         InputGetBinBlock(Handler, (VoidPtr) (TV -> VKnotVector), Size);
  669.         Size = sizeof(CagdRType) *
  670.             (TV -> WLength + TV -> WOrder +
  671.              (TV -> WPeriodic ? TV -> WOrder - 1 : 0));
  672.         TV -> WKnotVector = (CagdRType *) IritMalloc(Size);
  673.         InputGetBinBlock(Handler, (VoidPtr) (TV -> WKnotVector), Size);
  674.     }
  675.  
  676.     if (SHead == NULL) {
  677.         SHead = STail = TV;
  678.     }
  679.     else {
  680.         STail -> Pnext = TV;
  681.         STail = TV;
  682.     }
  683.     }
  684.     if (Sync != IP_OBJ_AUX_END || SHead == NULL)
  685.     _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  686.  
  687.     return SHead;
  688. }
  689.  
  690. /*****************************************************************************
  691. * DESCRIPTION:                                                               *
  692. * Routine to get a matrix from bin input stream.                 *
  693. *                                                                            *
  694. * PARAMETERS:                                                                *
  695. *   Handler:   A handler to the open stream.                     *
  696. *                                                                            *
  697. * RETURN VALUE:                                                              *
  698. *   MatrixType *:   Read matrix.                                             *
  699. *****************************************************************************/
  700. static MatrixType *InputGetBinMatrix(int Handler)
  701. {
  702.     MatrixType *Mat;
  703.  
  704.     if (InputGetBinSync(Handler, TRUE) != IP_OBJ_AUX_MATRIX)
  705.     _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  706.     Mat = (MatrixType *) IritMalloc(sizeof(MatrixType));
  707.     InputGetBinBlock(Handler, (VoidPtr) Mat, sizeof(MatrixType));
  708.  
  709.     return Mat;
  710. }
  711.  
  712. /*****************************************************************************
  713. * DESCRIPTION:                                                               *
  714. * Routine to get a string from bin input stream.                 *
  715. *                                                                            *
  716. * PARAMETERS:                                                                *
  717. *   Handler:   A handler to the open stream.                     *
  718. *                                                                            *
  719. * RETURN VALUE:                                                              *
  720. *   char *:   Read string.                                                   *
  721. *****************************************************************************/
  722. static char *InputGetBinString(int Handler)
  723. {
  724.     long Len;
  725.     char *Str;
  726.  
  727.     if (InputGetBinSync(Handler, TRUE) != IP_OBJ_AUX_STRING)
  728.     _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  729.     InputGetBinBlock(Handler, (VoidPtr) &Len, sizeof(long));
  730.     Str = (char *) IritMalloc(Len);
  731.     InputGetBinBlock(Handler, (VoidPtr) Str, Len);
  732.     return Str;
  733. }
  734.  
  735. /*****************************************************************************
  736. * DESCRIPTION:                                                               *
  737. * Routine to get a list of objects from bin input stream.             *
  738. *                                                                            *
  739. * PARAMETERS:                                                                *
  740. *   Handler:   A handler to the open stream.                     *
  741. *   Len:       Number of objects in list.                     *
  742. *                                                                            *
  743. * RETURN VALUE:                                                              *
  744. *   IPObjectStruct **:   Read list of objects.                               *
  745. *****************************************************************************/
  746. static IPObjectStruct **InputGetBinOList(int Handler, int Len)
  747. {
  748.     int i;
  749.     struct IPObjectStruct *PTmp,
  750.     **PObjList = (IPObjectStruct **)
  751.         IritMalloc(Len * sizeof(IPObjectStruct *));
  752.  
  753.     if (InputGetBinSync(Handler, TRUE) != IP_OBJ_AUX_OLST)
  754.     _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  755.     InputGetBinBlock(Handler, (VoidPtr) PObjList, Len * sizeof(IPObjectStruct *));
  756.  
  757.     for (i = 0; i < Len && PObjList[i] != NULL; i++) {
  758.     int Sync = InputGetBinSync(Handler, TRUE);
  759.  
  760.     PTmp = IPAllocObject("", IP_OBJ_UNDEF, NULL);
  761.     IritPrsrGetBinObjectAux(Handler, PTmp, Sync);
  762.     PObjList[i] = PTmp;
  763.     }
  764.     if (i < Len - 1)
  765.     PObjList[i] = NULL;
  766.  
  767.     return PObjList;
  768. }
  769.  
  770. /*****************************************************************************
  771. * DESCRIPTION:                                                               *
  772. * Routine to get a list of attributes from bin input stream.             *
  773. *                                                                            *
  774. * PARAMETERS:                                                                *
  775. *   Handler:   A handler to the open stream.                     *
  776. *                                                                            *
  777. * RETURN VALUE:                                                              *
  778. *   IPAttributeStruct *:   Read list of attributes.                          *
  779. *****************************************************************************/
  780. static IPAttributeStruct *InputGetBinAttributes(int Handler)
  781. {
  782.     int Sync;
  783.     IPAttributeStruct *Attr,
  784.     *ATail = NULL,
  785.     *AHead = NULL;
  786.  
  787.     while ((Sync = InputGetBinSync(Handler, TRUE)) == IP_OBJ_AUX_ATTR) {
  788.     long Len;
  789.  
  790.     Attr = (IPAttributeStruct *) IritMalloc(sizeof(IPAttributeStruct));
  791.     InputGetBinBlock(Handler, (VoidPtr) Attr, sizeof(IPAttributeStruct));
  792.     InputGetBinBlock(Handler, (VoidPtr) &Len, sizeof(long));
  793.     Attr -> Name = IritMalloc(Len);
  794.     InputGetBinBlock(Handler, (VoidPtr) (Attr -> Name), Len);
  795.     if (Attr -> Type == IP_ATTR_STR) {
  796.         if (InputGetBinSync(Handler, TRUE) != IP_OBJ_AUX_STRING)
  797.         _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  798.         InputGetBinBlock(Handler, (VoidPtr) &Len, sizeof(long));
  799.         Attr -> U.Str = IritMalloc(Len);
  800.         InputGetBinBlock(Handler, (VoidPtr) (Attr -> U.Str), Len);
  801.     }
  802.     else if (Attr -> Type == IP_ATTR_OBJ)
  803.         Attr -> U.PObj = IritPrsrGetBinObject(Handler);
  804.  
  805.     if (AHead) {
  806.         ATail -> Pnext = Attr;
  807.         ATail = Attr;
  808.     }
  809.     else {
  810.         ATail = AHead = Attr;
  811.     }
  812.     }
  813.     if (Sync != IP_OBJ_AUX_END)
  814.     _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  815.  
  816.     return AHead;
  817. }
  818.  
  819. /*****************************************************************************
  820. * DESCRIPTION:                                                               M
  821. * Routine to write one object to a given binary file, directly.             M
  822. *    Objects may be recursively defined, as lists of objects.             M
  823. *                                                                            *
  824. * PARAMETERS:                                                                M
  825. *   Handler:   A handler to the open stream.                     *
  826. *   PObj:      Object to write.                                              M
  827. *                                                                            *
  828. * RETURN VALUE:                                                              M
  829. *   void                                                                     M
  830. *                                                                            *
  831. * KEYWORDS:                                                                  M
  832. *   IritPrsrPutBinObject, files, parser                                      M
  833. *****************************************************************************/
  834. void IritPrsrPutBinObject(int Handler, IPObjectStruct *PObj)
  835. {
  836.     int i;
  837.     long Len;
  838.     IPObjectStruct *PTmp;
  839.  
  840.     /* If the following gain control and is non zero - its from error! */
  841.     if (setjmp(_IritPrsrLongJumpBuffer) != 0) {
  842.     /* Error had occured (and will be reported). */
  843.     return;
  844.     }
  845.  
  846.     OutputPutBinSync(Handler, PObj -> ObjType);
  847.     OutputPutBinBlock(Handler, (VoidPtr) PObj, sizeof(IPObjectStruct));
  848.     if (PObj -> Attrs != NULL)
  849.     OutputPutBinAttributes(Handler, PObj -> Attrs);
  850.  
  851.     switch (PObj -> ObjType) {
  852.     case IP_OBJ_POLY:
  853.         OutputPutBinPolys(Handler, PObj -> U.Pl);
  854.         break;
  855.     case IP_OBJ_NUMERIC:
  856.         break;
  857.     case IP_OBJ_POINT:
  858.         break;
  859.     case IP_OBJ_VECTOR:
  860.         break;
  861.     case IP_OBJ_PLANE:
  862.         break;
  863.     case IP_OBJ_MATRIX:
  864.         OutputPutBinSync(Handler, IP_OBJ_AUX_MATRIX);
  865.         OutputPutBinBlock(Handler, (VoidPtr) (*PObj -> U.Mat),
  866.                   sizeof(MatrixType));
  867.         break;
  868.     case IP_OBJ_CURVE:
  869.         OutputPutBinCurves(Handler, PObj -> U.Crvs);
  870.         break;
  871.     case IP_OBJ_SURFACE:
  872.         OutputPutBinSurfaces(Handler, PObj -> U.Srfs);
  873.         break;
  874.     case IP_OBJ_TRIMSRF:
  875.         OutputPutBinTrimSrfs(Handler, PObj -> U.TrimSrfs);
  876.         break;
  877.     case IP_OBJ_TRIVAR:
  878.         OutputPutBinTrivars(Handler, PObj -> U.Trivars);
  879.         break;
  880.     case IP_OBJ_STRING:
  881.         OutputPutBinSync(Handler, IP_OBJ_AUX_STRING);
  882.         Len = strlen(PObj -> U.Str) + 1;
  883.         OutputPutBinBlock(Handler, (VoidPtr) &Len, sizeof(long));
  884.         OutputPutBinBlock(Handler, (VoidPtr) (PObj -> U.Str), Len);
  885.         break;
  886.     case IP_OBJ_LIST_OBJ:
  887.         OutputPutBinSync(Handler, IP_OBJ_AUX_OLST);
  888.         OutputPutBinBlock(Handler, (VoidPtr) PObj -> U.Lst.PObjList,
  889.             sizeof(IPObjectStruct *) * PObj -> U.Lst.ListMaxLen);
  890.         for (i = 0;
  891.          i < PObj -> U.Lst.ListMaxLen &&
  892.          (PTmp = ListObjectGet(PObj, i)) != NULL;
  893.          i++) {
  894.         IritPrsrPutBinObject(Handler, PTmp);
  895.         }
  896.         break;
  897.     case IP_OBJ_CTLPT:
  898.         break;
  899.     default:
  900.         _IPParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  901.     }
  902. }
  903.  
  904. /*****************************************************************************
  905. * DESCRIPTION:                                                               *
  906. * Routine to put a list of polys to bin output stream.                 *
  907. *                                                                            *
  908. * PARAMETERS:                                                                *
  909. *   Handler:   A handler to the open stream.                     *
  910. *   Pl:        Polys to write.                                               *
  911. *                                                                            *
  912. * RETURN VALUE:                                                              *
  913. *   void                                                                     *
  914. *****************************************************************************/
  915. static void OutputPutBinPolys(int Handler, IPPolygonStruct *Pl)
  916. {
  917.     for (; Pl != NULL; Pl = Pl -> Pnext) {
  918.     IPVertexStruct
  919.         *V = Pl -> PVertex;
  920.  
  921.     OutputPutBinSync(Handler, IP_OBJ_AUX_POLY);
  922.     OutputPutBinBlock(Handler, (VoidPtr) Pl, sizeof(IPPolygonStruct));
  923.     if (Pl -> Attrs != NULL)
  924.         OutputPutBinAttributes(Handler, Pl -> Attrs);
  925.  
  926.     do {
  927.         OutputPutBinSync(Handler, IP_OBJ_AUX_VERTEX);
  928.         OutputPutBinBlock(Handler, (VoidPtr) V, sizeof(IPVertexStruct));
  929.         if (V -> Attrs != NULL)
  930.         OutputPutBinAttributes(Handler, V -> Attrs);
  931.         V = V -> Pnext;
  932.     }
  933.     while (V != NULL && V != Pl -> PVertex);
  934.     OutputPutBinSync(Handler, IP_OBJ_AUX_END);
  935.     }
  936.     OutputPutBinSync(Handler, IP_OBJ_AUX_END);
  937. }
  938.  
  939. /*****************************************************************************
  940. * DESCRIPTION:                                                               *
  941. * Routine to put a list of curves to bin output stream.                 *
  942. *                                                                            *
  943. * PARAMETERS:                                                                *
  944. *   Handler:   A handler to the open stream.                     *
  945. *   Crv:       Curves to write.                                              *
  946. *                                                                            *
  947. * RETURN VALUE:                                                              *
  948. *   void                                                                     *
  949. *****************************************************************************/
  950. static void OutputPutBinCurves(int Handler, CagdCrvStruct *Crv)
  951. {
  952.     for ( ; Crv != NULL; Crv = Crv -> Pnext) {
  953.     int i,
  954.         Size = sizeof(CagdRType) * Crv -> Length;
  955.  
  956.     OutputPutBinSync(Handler, IP_OBJ_AUX_CURVE);
  957.     OutputPutBinBlock(Handler, (VoidPtr) Crv, sizeof(CagdCrvStruct));
  958.  
  959.     for (i = !CAGD_IS_RATIONAL_PT(Crv -> PType);
  960.          i <= CAGD_NUM_OF_PT_COORD(Crv -> PType);
  961.          i++) {
  962.         OutputPutBinBlock(Handler, (VoidPtr) (Crv -> Points[i]), Size);
  963.     }
  964.  
  965.     if (Crv -> GType == CAGD_CBSPLINE_TYPE) {
  966.         Size = sizeof(CagdRType) *
  967.             (Crv -> Length + Crv -> Order +
  968.              (Crv -> Periodic ? Crv -> Order - 1 : 0));
  969.         OutputPutBinBlock(Handler, (VoidPtr) (Crv -> KnotVector), Size);
  970.     }
  971.     }
  972.     OutputPutBinSync(Handler, IP_OBJ_AUX_END);
  973. }
  974.  
  975. /*****************************************************************************
  976. * DESCRIPTION:                                                               *
  977. * Routine to put a list of surface to bin output stream.             *
  978. *                                                                            *
  979. * PARAMETERS:                                                                *
  980. *   Handler:   A handler to the open stream.                     *
  981. *   Srf:       Surfaces to write.                                            *
  982. *                                                                            *
  983. * RETURN VALUE:                                                              *
  984. *   void                                                                     *
  985. *****************************************************************************/
  986. static void OutputPutBinSurfaces(int Handler, CagdSrfStruct *Srf)
  987. {
  988.     for ( ; Srf != NULL; Srf = Srf -> Pnext) {
  989.     int i,
  990.         Size = sizeof(CagdRType) * Srf -> ULength * Srf -> VLength;
  991.  
  992.     OutputPutBinSync(Handler, IP_OBJ_AUX_SURFACE);
  993.     OutputPutBinBlock(Handler, (VoidPtr) Srf, sizeof(CagdSrfStruct));
  994.  
  995.     for (i = !CAGD_IS_RATIONAL_PT(Srf -> PType);
  996.          i <= CAGD_NUM_OF_PT_COORD(Srf -> PType);
  997.          i++) {
  998.         OutputPutBinBlock(Handler, (VoidPtr) (Srf -> Points[i]), Size);
  999.     }
  1000.  
  1001.     if (Srf -> GType == CAGD_SBSPLINE_TYPE) {
  1002.         Size = sizeof(CagdRType) *
  1003.             (Srf -> ULength + Srf -> UOrder +
  1004.              (Srf -> UPeriodic ? Srf -> UOrder - 1 : 0));
  1005.         OutputPutBinBlock(Handler, (VoidPtr) (Srf -> UKnotVector), Size);
  1006.         Size = sizeof(CagdRType) *
  1007.             (Srf -> VLength + Srf -> VOrder +
  1008.              (Srf -> VPeriodic ? Srf -> VOrder - 1 : 0));
  1009.         OutputPutBinBlock(Handler, (VoidPtr) (Srf -> VKnotVector), Size);
  1010.     }
  1011.     }
  1012.     OutputPutBinSync(Handler, IP_OBJ_AUX_END);
  1013. }
  1014.  
  1015. /*****************************************************************************
  1016. * DESCRIPTION:                                                               *
  1017. * Routine to put a list of trimmed surfaces to bin output stream.         *
  1018. *                                                                            *
  1019. * PARAMETERS:                                                                *
  1020. *   Handler:   A handler to the open stream.                     *
  1021. *   TrimSrf:   Trimmed surfaces to write.                                    *
  1022. *                                                                            *
  1023. * RETURN VALUE:                                                              *
  1024. *   void                                                                     *
  1025. *****************************************************************************/
  1026. static void OutputPutBinTrimSrfs(int Handler, TrimSrfStruct *TrimSrf)
  1027. {
  1028.     for ( ; TrimSrf != NULL; TrimSrf = TrimSrf -> Pnext) {
  1029.     TrimCrvStruct
  1030.         *TrimCrv = TrimSrf -> TrimCrvList;
  1031.  
  1032.     OutputPutBinSync(Handler, IP_OBJ_AUX_TRIMSRF);
  1033.     OutputPutBinBlock(Handler, (VoidPtr) (TrimSrf), sizeof(TrimSrfStruct));
  1034.     OutputPutBinSurfaces(Handler, TrimSrf -> Srf);
  1035.     for ( ; TrimCrv != NULL; TrimCrv = TrimCrv -> Pnext) {
  1036.         TrimCrvSegStruct
  1037.         *TrimCrvSeg = TrimCrv -> TrimCrvSegList;
  1038.  
  1039.         OutputPutBinSync(Handler, IP_OBJ_AUX_TRIMCRV);
  1040.         OutputPutBinBlock(Handler, (VoidPtr) (TrimCrv), sizeof(TrimCrvStruct));
  1041.  
  1042.         for ( ; TrimCrvSeg != NULL; TrimCrvSeg = TrimCrvSeg -> Pnext) {
  1043.         OutputPutBinSync(Handler, IP_OBJ_AUX_TRIMCRVSEG);
  1044.         OutputPutBinBlock(Handler, (VoidPtr) (TrimCrvSeg),
  1045.                   sizeof(TrimCrvSegStruct));
  1046.  
  1047.         OutputPutBinCurves(Handler, TrimCrvSeg -> UVCrv);
  1048.         }
  1049.         OutputPutBinSync(Handler, IP_OBJ_AUX_END);
  1050.     }
  1051.     OutputPutBinSync(Handler, IP_OBJ_AUX_END);
  1052.     }
  1053.     OutputPutBinSync(Handler, IP_OBJ_AUX_END);
  1054. }
  1055.  
  1056. /*****************************************************************************
  1057. * DESCRIPTION:                                                               *
  1058. * Routine to put a list of trivairates to bin output stream.             *
  1059. *                                                                            *
  1060. * PARAMETERS:                                                                *
  1061. *   Handler:   A handler to the open stream.                     *
  1062. *   TV:        Trivariates to write.                                         *
  1063. *                                                                            *
  1064. * RETURN VALUE:                                                              *
  1065. *   void                                                                     *
  1066. *****************************************************************************/
  1067. static void OutputPutBinTrivars(int Handler, TrivTVStruct *TV)
  1068. {
  1069.     for ( ; TV != NULL; TV = TV -> Pnext) {
  1070.     int i,
  1071.         Size = sizeof(CagdRType) *
  1072.                    TV -> ULength * TV -> VLength  * TV -> WLength;
  1073.  
  1074.     OutputPutBinSync(Handler, IP_OBJ_AUX_TRIVAR);
  1075.     OutputPutBinBlock(Handler, (VoidPtr) TV, sizeof(TrivTVStruct));
  1076.  
  1077.     for (i = !CAGD_IS_RATIONAL_PT(TV -> PType);
  1078.          i <= CAGD_NUM_OF_PT_COORD(TV -> PType);
  1079.          i++) {
  1080.         OutputPutBinBlock(Handler, (VoidPtr) (TV -> Points[i]), Size);
  1081.     }
  1082.  
  1083.     if (TV -> GType == TRIV_TVBSPLINE_TYPE) {
  1084.         Size = sizeof(CagdRType) *
  1085.             (TV -> ULength + TV -> UOrder +
  1086.              (TV -> UPeriodic ? TV -> UOrder - 1 : 0));
  1087.         OutputPutBinBlock(Handler, (VoidPtr) (TV -> UKnotVector), Size);
  1088.         Size = sizeof(CagdRType) *
  1089.             (TV -> VLength + TV -> VOrder +
  1090.              (TV -> VPeriodic ? TV -> VOrder - 1 : 0));
  1091.         OutputPutBinBlock(Handler, (VoidPtr) (TV -> VKnotVector), Size);
  1092.         Size = sizeof(CagdRType) *
  1093.             (TV -> WLength + TV -> WOrder +
  1094.              (TV -> WPeriodic ? TV -> WOrder - 1 : 0));
  1095.         OutputPutBinBlock(Handler, (VoidPtr) (TV -> WKnotVector), Size);
  1096.     }
  1097.     }
  1098.     OutputPutBinSync(Handler, IP_OBJ_AUX_END);
  1099. }
  1100.  
  1101. /*****************************************************************************
  1102. * DESCRIPTION:                                                               *
  1103. * Routine to put a list of attributes to bin output stream.             *
  1104. *                                                                            *
  1105. * PARAMETERS:                                                                *
  1106. *   Handler:   A handler to the open stream.                     *
  1107. *   Attrs:     Attributes to write.                                          *
  1108. *                                                                            *
  1109. * RETURN VALUE:                                                              *
  1110. *   void                                                                     *
  1111. *****************************************************************************/
  1112. static void OutputPutBinAttributes(int Handler, IPAttributeStruct *Attrs)
  1113. {
  1114.     Attrs = AttrTraceAttributes(Attrs, Attrs);
  1115.  
  1116.     while (Attrs) {
  1117.     if (Attrs -> Name[0] != '_' &&
  1118.         (Attrs -> Type == IP_ATTR_INT ||
  1119.          Attrs -> Type == IP_ATTR_REAL ||
  1120.          Attrs -> Type == IP_ATTR_STR ||
  1121.          Attrs -> Type == IP_ATTR_OBJ)) {
  1122.         long
  1123.         Len = strlen(Attrs -> Name) + 1;
  1124.  
  1125.         OutputPutBinSync(Handler, IP_OBJ_AUX_ATTR);
  1126.         OutputPutBinBlock(Handler, (VoidPtr) Attrs,
  1127.                   sizeof(IPAttributeStruct));
  1128.         OutputPutBinBlock(Handler, (VoidPtr) &Len, sizeof(long));
  1129.         OutputPutBinBlock(Handler, (VoidPtr) (Attrs -> Name), Len);
  1130.  
  1131.         if (Attrs -> Type == IP_ATTR_STR) {
  1132.         Len = strlen(Attrs -> U.Str) + 1;
  1133.  
  1134.         OutputPutBinSync(Handler, IP_OBJ_AUX_STRING);
  1135.         OutputPutBinBlock(Handler, (VoidPtr) &Len, sizeof(long));
  1136.         OutputPutBinBlock(Handler, (VoidPtr) (Attrs -> U.Str), Len);
  1137.         }
  1138.         else if (Attrs -> Type == IP_ATTR_OBJ)
  1139.         IritPrsrPutBinObject(Handler, Attrs -> U.PObj);
  1140.     }
  1141.  
  1142.     Attrs = AttrTraceAttributes(Attrs, NULL);
  1143.     }
  1144.     OutputPutBinSync(Handler, IP_OBJ_AUX_END);
  1145. }
  1146.